import { createStore, applyMiddleware } from 'redux';
import createSagaMiddleware from 'redux-saga';
import { call, select, put as _put, take, fork } from 'redux-saga/effects';
import { Provider, connect } from 'react-redux';
import { composeWithDevTools } from 'redux-devtools-extension'
import _ from 'lodash';
import model from './model';

const { state: initState, effects, reducers } = model;

function reducer(state = initState, action) {
  const { type } = action;
  if (_.isFunction(reducers[type])) {
    return reducers[type](state, action);
  } else {
    return state;
  }
}

function* takeEvery(pattern, saga, ...args) {
  while(true) {
    const action = yield take(pattern);
    yield fork(saga, ...[action].concat(args));
  }
}

const funcs = { call, put, select };

function* put({ type, payload }) {
  yield _put({ type, payload });
  if (_.isFunction(effects[type])) {
    yield call(effects[type], { type, payload }, funcs);
  }
}

function* sagas() {
  yield* _.map(effects, function* (effect, name) {
    yield* takeEvery(name, effects[name], funcs);
  });
}

const sagaMiddleware = createSagaMiddleware();
const composeEnhancers = composeWithDevTools({
  name: 'test33332222',
});

const store = createStore(
  reducer,
  composeEnhancers(
    applyMiddleware(
      sagaMiddleware,
    ),
  )
);
sagaMiddleware.run(sagas);

export default store;
export {
  Provider,
  connect,
}
